home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / pt20pc.zip / MENU.C < prev    next >
C/C++ Source or Header  |  1991-02-04  |  12KB  |  432 lines

  1. #include "pt.h"
  2. #include "memory.h"
  3. #include "malloc.h"
  4. #include "string.h"
  5.  
  6. void pascal
  7. /* XTAG:pulldown */
  8. pulldown(menuNumber)
  9.     int menuNumber;
  10. {
  11.     extern unsigned char msgBuffer[];
  12.     extern int menuLine;
  13.     extern struct menuBlock far *menus[];
  14.     extern int scrRows, scrCols;
  15.     extern unsigned char topColor;
  16.     extern int menuShowing;
  17.     
  18.     register int i;
  19.     int limit, col, row;
  20.     unsigned char far *fp;
  21.     
  22.     if( menuLine == 0 )
  23.         return;
  24.     limit = menus[menuNumber]->nItems;
  25.     col = 0;
  26.     row = (menuLine > 0 ? 0 : (scrRows-1) );
  27.     for(i = 1; i < limit; i++) {
  28.         fp = menus[menuNumber]->cmdName[i];
  29.         while( *fp != '\0' ) {
  30.             displayChar(row, col++, *fp++, topColor);
  31.             if( col >= scrCols )
  32.                 return;
  33.         }
  34.     }
  35.     while( col < scrCols )
  36.         displayChar(row, col++, ' ', topColor);
  37.     /* remember which menu is up for showing descriptions */
  38.     menuShowing = menuNumber;
  39. }
  40.  
  41. int pascal
  42. /* XTAG:menu */
  43. menu(thisMenu, row1, col1)
  44.     struct menuBlock far *thisMenu;
  45.     int row1, col1;
  46. {
  47.     extern unsigned char msgBuffer[];
  48.     extern unsigned char textBuffer[];
  49.     extern unsigned char border2[];
  50.     extern union REGS rin, rout;
  51.     extern struct SREGS segRegs;
  52.     extern unsigned char *screenChars;
  53.     extern int debug;
  54.     extern unsigned char bannerColor, borderColor, elevColor;
  55.     extern unsigned char textColor, selColor;
  56.     extern int scrRows, scrCols;
  57.     extern struct event events[];
  58.     extern struct menuBlock far *menus[];
  59.     extern int mousePresent;
  60.     extern int i43lines;
  61.     extern int descrFileId;
  62.     extern int helpMode;
  63.     extern unsigned char *userMessages[];
  64.     extern int lastCommand;
  65.     extern int menuLine;
  66.     extern int centerMenus;
  67.     extern struct optionItem options[];
  68.     extern struct window *activeWindow;
  69.     extern unsigned char msgColor, promptColor, errorColor, topColor;
  70.     extern int toplineMenu;
  71.  
  72.     int i, j, n, row, col, row2, col2, numItems, maxSize, fn;
  73.     int attr, selRow, curRow, curCol, lastRow, lastCol;
  74.     int oldSelRow, r1, r2;
  75.     int chordExit, startButtons;
  76.     int evhead;
  77.     int menuNumber;
  78.     unsigned char far *sBuffer;
  79.     unsigned int sizeOfBuffer;
  80.     unsigned char key, scan, ch;
  81.     unsigned char far *fname;
  82.     int restart;
  83.  
  84. startOver:
  85.     restart = 0;
  86.     /* get the present mouse button state */
  87.     if( mousePresent ) {
  88.         rin.x.ax = 3;
  89.         int86(51, &rin, &rout);
  90.         startButtons = rout.x.bx;
  91.     } else
  92.         startButtons = 0x0;
  93.     chordExit = 0;    /* set to 1 if any buttons change */
  94.  
  95.     /* it is only necessary to differentiate between menu 0 */
  96.     /* and all other menus so this will suffice */
  97.     if( thisMenu == menus[0] )
  98.         menuNumber = 0;
  99.     else
  100.         menuNumber = 1;
  101.     numItems = thisMenu->nItems;
  102.     if( numItems <= 0 )
  103.         return FDONOTHING;
  104.     maxSize = 0;
  105.     for(n = 0; n < numItems; n++) {
  106.         /* see if this is an option menu item */
  107.         fn = thisMenu->cmdNumber[n];
  108.         if( FFIRSTOPTION <= fn && fn <= FLASTOPTION ) {
  109.                 /* 70 should handle the largest option string */
  110.             thisMenu->cmdName[n] =
  111.                 (unsigned char far *)_fmalloc(70);
  112.             /* create the option string */
  113.             i = 0;
  114.             while( options[i].commandNumber != fn ) {
  115.                 if( options[i].index == OLASTITEM ) {
  116.                     sprintf(msgBuffer,
  117. "Unknown option command [%d]; ignored in menu", fn);
  118.                     goto loopAgain;
  119.                 }
  120.                 ++i;
  121.             }
  122.             switch( options[i].type ) {
  123.             case OBOOLEAN:
  124.             case UBOOLEAN:
  125.                 sprintf(msgBuffer,"%s is %s",options[i].name,
  126.                     (*(options[i].variable)?"On":"Off"));
  127.                 break;
  128.             case OINTEGER:
  129.             case UINTEGER:
  130.                 sprintf(msgBuffer,"%s = %d",options[i].name,
  131.                     *(options[i].variable));
  132.                 break;
  133.             case OSTRING:
  134.             case USTRING:
  135.                 sprintf(msgBuffer,"%s = %s",options[i].name,
  136.                     options[i].variable);
  137.                 break;
  138.             case OOTHERS:
  139.             case UOTHERS:
  140.                 switch(options[i].index) {
  141.                 case OTEXTCOLORS:
  142.                     sprintf(msgBuffer,"%s = %02X%02X",
  143.                         options[i].name,
  144.                         activeWindow->textColor,
  145.                         activeWindow->selColor);
  146.                     break;
  147.                 case OBORDERCOLORS:
  148.                     sprintf(msgBuffer,"%s = %02X%02X%02X",
  149.                         options[i].name,
  150.                         activeWindow->bannerColor,
  151.                         activeWindow->borderColor,
  152.                         activeWindow->elevColor);
  153.                     break;
  154.                 case OMSGCOLORS:
  155.                     sprintf(msgBuffer,
  156.                         "%s = %02X%02X%02X%02X",
  157.                         options[i].name,
  158.                         msgColor, promptColor,
  159.                         errorColor, topColor);
  160.                     break;
  161.                 case OREDEFINE:
  162.                     sprintf(msgBuffer, "%s",
  163.                         options[i].name);
  164.                 }
  165.                 break;
  166.             }
  167.             sBuffer = thisMenu->cmdName[n];
  168.             movedata(segRegs.ds, (unsigned)msgBuffer,
  169.                 FP_SEG(sBuffer), FP_OFF(sBuffer),
  170.                 strlen(msgBuffer)+1);
  171.                 /* +1 to move the '\0' */
  172.         }
  173.         j = farStrlen(thisMenu->cmdName[n]);
  174.         if( n == 0 )
  175.             j += 4;
  176.         if( j > maxSize )
  177.             maxSize = j;
  178.     loopAgain:
  179.         ;
  180.     }
  181.     row2 = row1 + numItems;
  182.     /* double space in 43 line mode (so menus are easier to read) */
  183.     if( i43lines && numItems <= 19 )
  184.         row2 += numItems;
  185.     col2 = col1 + maxSize + 5; /* so centering looks better */
  186.         /* 5 = 4 (2 spaces on each side of names) + 1 (col1->col2) */
  187.     /* if not centering menus, just add one space on each side */
  188.     if( !centerMenus )
  189.         col2 -= 2;
  190.     /* adjust the dimensions so that the menu always fits on the screen */
  191.     if( row2 > (scrRows-1) ) {
  192.         row1 -= (row2 - (scrRows-1));
  193.         row2 = (scrRows-1);
  194.         if( menuLine < 0 ) {
  195.             /* a fix so that the menus do not cover the */
  196.             /* message lien when using bottom line menus */
  197.             if( row1 > 1 ) {
  198.                 row1 -= 2;
  199.                 row2 -= 2;
  200.             } else if( row1 > 0 ) {
  201.                 --row1;
  202.                 --row2;
  203.             }
  204.         }
  205.     }
  206.     if( col2 > (scrCols-1) ) {
  207.         col1 -= (col2 - (scrCols-1));
  208.         col2 = (scrCols-1);
  209.     }
  210.  
  211. /* ELIMINATE THIS WHEN YOU ELIMINATE screenChars */
  212.     /* save the present screen characters */
  213.     /* allocate some memory to hold the screen image */
  214.     sizeOfBuffer = (unsigned)((scrCols<<1)*(row2-row1+1));
  215.     sBuffer = _fmalloc(sizeOfBuffer);
  216.     if( sBuffer == 0L ) {
  217.         msg(userMessages[NOSPACEMSG], 3);
  218.         return FDONOTHING;
  219.     }
  220.     movedata(segRegs.ds, (int)(screenChars+(scrCols<<1)*row1),
  221.         FP_SEG(sBuffer), FP_OFF(sBuffer), sizeOfBuffer);
  222.  
  223.     /* set up the map and draw the menu */
  224.     setMap(row1, col1, row2, col2, 2, textColor);
  225.     
  226.     /* draw the menu name in */
  227.     fname = thisMenu->cmdName[0];
  228.     col = col1 + (col2-col1-farStrlen(fname)-3)/2;
  229.     displayChar(row1, col++, 16, elevColor);
  230.     displayChar(row1, col++, ' ', elevColor);
  231.     for(i = 0; fname[i] != '\0'; i++)
  232.         displayChar(row1, col++, fname[i], elevColor);
  233.     displayChar(row1, col++, ' ', elevColor);
  234.     displayChar(row1, col++, 17, elevColor);
  235.     
  236.     /* draw the border */
  237.     drawBorder(&border2[0], row1, col1, row2, col2, borderColor, 0);
  238.  
  239.     selRow = row1;
  240.     lastRow = curRow = row1;
  241.     lastCol = curCol = col1;
  242.     oldSelRow = -1;
  243.     /* start by prompting with the menus "comment" */
  244. while( 1 ) {
  245.     /* first draw the menu */
  246.     setMap(row1+1, col1+1, row2-1, col2-1, 1, textColor);
  247.     row = row1 + 1;
  248.     if( i43lines && numItems <= 19 )
  249.         ++row;
  250.     fn = 0;
  251.     for(i = 1; i < numItems; i++) {
  252.         fname = thisMenu->cmdName[i];
  253.         col = col1 + 1;
  254.         j = 0;
  255.         if( row == selRow ) {    /* the selected item */
  256.             attr = selColor;
  257.             fn = i;
  258.         } else
  259.             attr = textColor;
  260.         if( centerMenus ) {
  261.             /* center the menu item */
  262.             n = (col2-col1-farStrlen(fname)-1)/2;
  263.         } else
  264.             n = 1;
  265.         while( n-- > 0 )
  266.             displayChar(row, col++, ' ', attr);
  267.         while( 1 ) {
  268.             ch = fname[j++];
  269.             if( ch == '\0' )
  270.                 break;
  271.             displayChar(row, col++, ch, attr);
  272.         }
  273.         while( col < col2 )
  274.             displayChar(row, col++, ' ', attr);
  275.         ++row;
  276.         /* double space menu items in 43 line mode */
  277.         if( i43lines && numItems <= 19 )
  278.             ++row;
  279.     }
  280.     if( oldSelRow == -1 ) {
  281.         /* first time -- write the whole menu */
  282.         r1 = row1;
  283.         r2 = row2;
  284.     } else {
  285.         if( oldSelRow == row1 )
  286.             /* no old selection to erase */
  287.             oldSelRow = selRow;
  288.         /* rewrite the old and new selection only */
  289.         r1 = min(oldSelRow, selRow);
  290.         r2 = max(oldSelRow, selRow);
  291.         if( selRow == row1 )
  292.             /* no new selection to rewrite */
  293.             r1 = oldSelRow;
  294.     }
  295.     updateScreen(r1, r2);
  296.     /* remember the last command selected (except the default) */
  297.     if( menuNumber != 0 && fn != 0 ) {
  298.         lastCommand = thisMenu->cmdNumber[fn];
  299.     }
  300.     if( menuNumber != 0 && helpMode > 0 ) {
  301.         /* if in help mode then